#!/usr/local/bin/python
#----------------------------------------------------------------
#
# Name:         dolphin.py
# 
# Author:       Dragon@Dragon Technology Co.,Ltd
#
# Created:      Apr 14th,2008
# 
# CopyRight:    (c) 2008-2010 dragon
#
# Licence:      BSD Licence 
#
#----------------------------------------------------------------

from list import *
from wx import *
from wx.lib.wordwrap import wordwrap
from wx.lib.ticker import Ticker
import xml.dom.minidom

#----------------------------------------------------------------

class MyApp(wx.App):
    def __init__(self):
        wx.App.__init__(self)
        self.OnInit
        
    def OnInit(self):

        win = MyFrame(None,
                      -1,
                      "dolphin music player V2.0",
                      pos=(120,200),
                      size=(710,480),
                      style=wx.CLOSE_BOX|wx.SYSTEM_MENU)
        win.CenterOnScreen()
        win.Show(True)
        return True

#-----------------------------------------------------------------        

class MyFrame(wx.Frame):
    def __init__(self,
                 parent,
                 ID,
                 title,
                 pos=wx.DefaultPosition,
                 size=wx.DefaultSize,
                 style=wx.CLOSE_BOX|wx.DEFAULT_FRAME_STYLE):

        wx.Frame.__init__(self,parent,ID,title,pos,size,style)
        self.Bind(wx.EVT_CLOSE,self.OnClose)
        self.SetBackgroundColour("#94a386")

        menuBar = wx.MenuBar()

        menu1 = wx.Menu()
        menu1.Append(101,"&Quit System","exit system")
        self.Bind(wx.EVT_MENU,self.OnClose,id=101)

        menu2 = wx.Menu()
        menu2.Append(201,"&build list","&Search media files and build data file")
        self.Bind(wx.EVT_MENU,self.OnBuildList,id=201)

        menu3 = wx.Menu()
        menu3.Append(301,"&About Me","information of this system")
        self.Bind(wx.EVT_MENU,self.OnAbout,id=301)
        menu3.AppendSeparator()
        menu3.Append(302,"&Help Online","online help system")

        menuBar.Append(menu1,"&General")
        menuBar.Append(menu2,"&Tools")
        menuBar.Append(menu3,"&About")
        self.SetMenuBar(menuBar)

#-----------------------------------------------------------------

        #create a timer update progress flag 100cm one times
        self.m_timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER,self.OnUpdate)

        # build a vertical area 
        sizer = wx.BoxSizer(wx.VERTICAL)

        # build a horizontal area
        body = wx.BoxSizer(wx.HORIZONTAL)
        body_left = wx.BoxSizer(wx.VERTICAL)

        self.media_play = self.create_media_play()
        body_left.Add(self.media_play,0,wx.ALL,10)
        self.cur_play_mode=0

        play_ctrl = wx.BoxSizer(wx.HORIZONTAL)
        progress_info = wx.StaticText(self,-1,"Progress:")
        play_ctrl.Add(progress_info,0,wx.ALL,0)

        self.progress = wx.Gauge(self,-1,50, pos = wx.DefaultPosition,size=(280,10))
        play_ctrl.Add(self.progress,0,wx.ALL,5)

        self.play_status=wx.StaticText(self,-1,"  Stop Status Now")
        play_ctrl.Add(self.play_status,0,wx.ALL,0)

        body_left.Add(play_ctrl,0,wx.ALL,10)
        body.Add(body_left,0,wx.ALL,0)

        #build the right area of body. 
        body_right = wx.BoxSizer(wx.VERTICAL)
        # build search toolbar
        self.m_search=wx.SearchCtrl(self,size=(190,-1),style=wx.TE_PROCESS_ENTER)
        body_right.Add(self.m_search,0,wx.ALL,10)                

        self.m_list = self.create_play_list(190,305)
        self.load_play_list()     
        self.Bind(wx.EVT_LIST_ITEM_SELECTED,self.OnSelect,self.m_list.list)
#         book.list.SetItemState(0,wx.LIST_STATE_SELECTED,wx.LIST_STATE_SELECTED)
        body_right.Add(self.m_list,0,wx.ALL,10)

        #build volum control slider
        volum = wx.BoxSizer(wx.HORIZONTAL)
        self.v_loop = wx.CheckBox(self,10,"loop")
        volum.Add(self.v_loop,0,wx.ALL,0)
        self.Bind(wx.EVT_CHECKBOX,self.OnSetLoopPlay,self.v_loop)

        self.v_radom = wx.CheckBox(self,20,"random")
        volum.Add(self.v_radom,0,wx.ALL,0)
        self.Bind(wx.EVT_CHECKBOX,self.OnSetRadomPlay,self.v_radom)

        self.v_vol = wx.CheckBox(self,30,"pause")#,style=wx.ALIGN_RIGHT)
        volum.Add(self.v_vol,0,wx.ALL,0)
        self.Bind(wx.EVT_CHECKBOX,self.OnPause,self.v_vol)
        body_right.Add(volum,0,wx.ALL,5)

        body.Add(body_right,0,wx.ALL,0)
        sizer.Add(body,0,wx.ALIGN_RIGHT|wx.ALL,10)

        self.SetSizer(sizer)
        sizer.Fit(self)
        
        # connect timer and execute function 
        self.m_timer.Start(1000)
                
#------------------------------------------------------------------------

    def create_media_play(self):
        play_area = wx.Panel(self,-1,pos=wx.DefaultPosition,size=(470,350))
        play_area.SetBackgroundColour("#2a795f")

        try:
            m_media = wx.media.MediaCtrl(play_area, 
                                         -1,
                                         wx.EmptyString,
                                         pos=(0,0),
                                         size=(470,350),
                                         style=wx.SIMPLE_BORDER,
                                         szBackend=wx.media.MEDIABACKEND_GSTREAMER
                                         #szBackend=wx.media.MEDIABACKEND_DIRECTSHOW
                                         #szBackend=wx.media.MEDIABACKEND_QUICKTIME
                                         #szBackend=wx.media.MEDIABACKEND_WMP10
                                         )
        except NotImplementedError:
            m_media.Destroy()
            raise
        self.m_media = m_media
        return play_area
    
    def create_play_list(self,width,height):
        play_list = wx.Panel(
            self,
            -1,
            pos=wx.DefaultPosition,
            size=(width,height),
            style=wx.WANTS_CHARS)

        play_list.SetBackgroundColour("#5f8e3e")
        play_list.SetAutoLayout(True)

        play_list.list = wx.ListCtrl(play_list, 
                                     -1, 
                                     pos=(0,0), 
                                     size=(width,height), 
                                     style=wx.LC_REPORT
                                     | wx.BORDER_NONE
                                     | wx.LC_EDIT_LABELS
                                     | wx.LC_SORT_ASCENDING
                                     | wx.LC_NO_HEADER
                                     | wx.LC_HRULES
                                     | wx.LC_SINGLE_SEL)
        play_list.list.InsertColumn(0,"music list",wx.LIST_FORMAT_LEFT)
        play_list.list.SetBackgroundColour("#e0e0cd")
        play_list.list.SetTextColour("#008000")

        return play_list

    def load_play_list(self):
        # read media alias from xml data file
        r_proc = readdata('list.conf')
        self.r_proc = r_proc

        info = wx.ListItem()
        info.m_mask = wx.LIST_MASK_TEXT|wx.LIST_MASK_FORMAT
        info.m_format = 0
#        info.SetColumn(0)

        items = r_proc.get_name_list()
        for m_alias in items:
            info.SetText(m_alias) 
            self.m_list.list.InsertItem(info)
#        self.m_list.list.SetColumnWidth(0,wx.LIST_AUTOSIZE) 
        self.m_list.list.SetColumnWidth(0,175)  

    def get_dirname(self):
        dir_name=None
        dlg = wx.DirDialog(self, "Choose a directory:",
                           style=wx.DD_DEFAULT_STYLE
                           | wx.DD_DIR_MUST_EXIST
                           | wx.DD_CHANGE_DIR
                           )
        # If the user selects OK, get the directory name.
        # we destroy it. 
        if dlg.ShowModal() == wx.ID_OK:
            dir_name = dlg.GetPath()
        # Only destroy a dialog after you're done with it.
        dlg.Destroy()
        return dir_name

    def play_media_file(self,target):
        self.stop_media_file()
        self.m_media.Load(target)
        self.Bind(wx.media.EVT_MEDIA_LOADED, self.OnPlay)

    def pause_media_file(self):
        if self.m_media != None:
            self.m_media.Pause()

    def stop_media_file(self):
        if self.m_media != None:
            self.m_media.Stop()

    def updata_progress(self):
        if not self.m_media == None:
            if self.m_media.GetState() == wx.media.MEDIASTATE_PLAYING or self.m_media.GetState() == wx.media.MEDIASTATE_PAUSED:
                llLength = self.m_media.Length()
                Minutes = llLength / 60000
                Seconds = (llLength % 60000)/1000
                llTell = self.m_media.Tell()
                nMinutes = llTell / 60000
                nSeconds = (llTell % 60000)/1000

                curtime = str(nMinutes) + ":" + str(nSeconds)
                alltime = str(Minutes) + ":" + str(Seconds)
                info = " Playing " + curtime + "/" + alltime
                self.play_status.Fit()
                self.play_status.SetLabel(info)

                self.progress.SetRange(llLength / 1000)
                self.progress.SetValue(llTell / 1000)

            else:
                if self.progress != None:
                    self.progress.SetValue(0)
                    self.play_status.SetLabel("  Stop Status Now")

#------------------------------------------------------------------
# process event after here.
#------------------------------------------------------------------
    def OnClose(self,event):
        self.stop_media_file()
        self.m_media.Destroy()
        self.Destroy()

    def OnBuildList(self,event):
        # create a hander of process xml data
        w_proc=writedata('list.conf')  
        self.w_proc = w_proc
        dir_name = self.get_dirname()
        self.w_proc.write_data_in(dir_name)
        wx.MessageBox("finish create data list\n update your play list \n",
                      "Finish",
                      wx.ICON_INFORMATION | wx.OK)
        self.load_play_list()

    def OnPause(self,event):
        if self.m_media.GetState() == wx.media.MEDIASTATE_PLAYING:
            self.pause_media_file()
        else:
            self.m_media.Play()

    def OnClick(self,event):
        str = self.text.GetValue()
        self.text.Clear()
        dlg=MyDialog(self,
                     -1,
                     str,
                     size=(640,480),
                     style=wx.DEFAULT_DIALOG_STYLE)        
        dlg.CenterOnScreen()
        dlg.ShowModal()

    def OnAbout(self, evt):
        # First we create and fill the info object
        info = wx.AboutDialogInfo()
        info.Name = "dolphin music player"
        info.Version = "2.0"
        info.Copyright = "(C) 2008-2010 dragon"
        info.Description = wordwrap(
            "\"dolphin\" is a music player, which can help you to play "
            "music file one after one. This software is so small and so strong!"
            "\n\n",
            400, wx.ClientDC(self))
        info.WebSite = ("http://i-cando.cn/dragon", "Author Home WebSite")
        info.Developers = [ "dragon xiao"]
        licenseText=" This program is free software and open source, It is have wrote by dragon with python . It can been working on more platform, just need python support."
        info.License = wordwrap(licenseText, 500, wx.ClientDC(self)) #
        
        wx.AboutBox(info)

    def OnSelect(self,evt):
        cur_item = evt.m_itemIndex
        media_name = self.m_list.list.GetItemText(cur_item)
        target_file = self.r_proc.get_fullname(media_name)
        self.play_media_file(target_file)
        evt.Skip()


    def OnPlay(self, evt):
        if not self.m_media.Play():
            wx.MessageBox("Unable to Play media : Unsupported format?",
                          "ERROR",
                          wx.ICON_ERROR | wx.OK)
#        else:
#            self.m_media.SetInitialSize()

    def OnUpdate(self,evt):
        self.updata_progress()

    def OnSetVolum(self,evt):  
#         if evt.IsChecked():
        vol_control = wx.Dialog(
            self,
            -1,
            "Volume Setting",
            size=wx.DefaultSize,
            style=wx.DEFAULT_DIALOG_STYLE)        
        
        v_sizer = wx.BoxSizer(wx.HORIZONTAL)
        vol_l = StaticText(vol_control,-1,"Vol:-")
        v_sizer.Add(vol_l,0,wx.ALL,0)
        
        self.volum=wx.Slider(vol_control,
                             wx.NewId(),
                             100,
                             0,
                             100,
                             size=(150,-1),
                             style=wx.SL_HORIZONTAL|wx.SL_AUTOTICKS)
        v_sizer.Add(self.volum,0,wx.ALL,0)
#             self.volum.SetValue(50)
        vol_r = StaticText(vol_control,-1,"+")
        v_sizer.Add(vol_r,0,wx.ALL,0)
        
        vol_control.SetSizer(v_sizer)
        v_sizer.Fit(vol_control)
        vol_control.ShowModal()

    def OnSetRadomPlay(self,evt):
        if evt.IsChecked():
            self.cur_play_mode=2
        else:
            self.cur_play_mode=0

    def OnSetLoopPlay(self,evt):
        if evt.IsChecked():
            self.cur_play_mode=1
        else:
            self.cur_play_mode=0        

#-----------------------------------------------------------------------        

class MyDialog(wx.Dialog):
    def __init__(self,
                 parent,
                 ID,
                 title,
                 size=wx.DefaultSize,
                 pos=wx.DefaultPosition,
                 style=wx.DEFAULT_DIALOG_STYLE):
        wx.Dialog.__init__(self,parent,ID,title,pos,size,style)        
        self.ticker = Ticker(self)            

#-----------------------------------------------------------------------



#-----------------------------------------------------------------------
# The Start enter of this program 
#-----------------------------------------------------------------------

if __name__ == "__main__":
    app = MyApp()
    app.MainLoop()
